#include <iostream>

#include "../inc/MainScreen.h"
#include "../inc/SimpleEngine.h"
#include "../inc/SkyBox.h"
#include "../inc/TargetCamera.h"
#include "../inc/WireBox.h"
#include "../inc/ArrowLine.h"
#include "../inc/LineMesh.h"
#include "../inc/ValueBillboard.h"

GLfloat ctrlpoints[3][3] = {{0.0, 0.0, 5.0}, {2.5, 10.0, 2.5}, {5.0, 0.0, 0.0}};
CoordF arrow[] = { CoordF(0,0,0.05), CoordF(0.3,0.3,0.05), CoordF(0.2,0.3,0.05), CoordF(0.2,0.8,0.05), CoordF(-0.2,0.8,0.05), CoordF(-0.2,0.3,0.05), CoordF(-0.3,0.3,0.05), CoordF(0,0,0.05), CoordF(0,0,-0.05), CoordF(0.3,0.3,-0.05), CoordF(0.2,0.3,-0.05), CoordF(0.2,0.8,-0.05), CoordF(-0.2,0.8,-0.05), CoordF(-0.2,0.3,-0.05), CoordF(-0.3,0.3,-0.05), CoordF(0,0,-0.05) };
LineMesh *lm;
char *texnames[] = { "../res/2.tga", "../res/8.tga", "../res/5.tga", "../res/0.tga", "../res/3.tga" };
int cellValues[] = { 2, 8, 5, 12, 0 };
        
MainScreen::MainScreen()
  : Screen(Screen::SCREEN_3D)
{
  Camera * tc = new Camera( CoordF(0,0,5) );
  registerCamera(tc);
  
  /**/
  sky = new SkyBox(1000, 1000, 1000);
  sky->setTex("../res/World.bmp");
  addDrawable(sky);
  
  /** /
  //Bezier line test
  glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 3, &ctrlpoints[0][0]);
  glEnable(GL_MAP1_VERTEX_3);
  /**/
  
  double cellStep = 5.0;
  for (int i=0;i<5;i++)
  {
    WireBox *wb = new WireBox(CoordF(i*cellStep,0,0),1.0,1.0,1.0, Color::BLUE);
    wb->toggleLighting();
    addDrawable(wb);
    if (i<4) addDrawable(new ArrowLine(CoordF(i*cellStep + 0.5,0,0), CoordF((i+1)*cellStep - 0.5,0,0)));
  }

  /**/
  // Line mesh test
  lm = new LineMesh( CoordF(10,1,0), arrow, 16);
  lm->material()->setMaterial(Color::GREEN);
  lm->toggleLighting();
  addDrawable(lm);

  /**/
  // Number plane test
  for (int i=0;i<5;i++)
  {
      ValueBillboard * p = new ValueBillboard();
      //Plane * p = new Plane();
      //p->setSize(1.0, 1.0);
      //p->material()->setMaterial( new Texture(texnames[i], Texture::NORMAL), Color::RED );
      p->material()->setMaterial(Color::RED);
      p->setValue(cellValues[i]);
      p->setWidth(1.0);
      p->setPos( CoordF(i*cellStep,0,0) );
      p->toggleLighting();
      addDrawable(p);
  }
 
  /**/
  int vp[4];
  glGetIntegerv(GL_VIEWPORT, vp);
  f = new GLFont(vp[2], vp[3]);
}

MainScreen::~MainScreen()
{
  if (lm) delete (lm);
  if (f) delete (f);
  if (sky) delete (sky);
}

void MainScreen::setup(int width, int height)
{
  Screen::setup(width, height);
  int vp[4];
  glGetIntegerv(GL_VIEWPORT, vp);
  f = new GLFont(vp[2], vp[3]);
}

void MainScreen::display(double dt)
{
  //Animation hack test
  if (lm) lm->rotate( CoordF( 0, 1, 0) );
  
  //std::cout << "Chamando updateAll(" << dt << ")" << std::endl;
  updateAll(dt);
  
  //glDisable(GL_LIGHTING);
  //std::cout << "Chamando drawAll()" << std::endl;
  drawAll();
  //glEnable(GL_LIGHTING);
   
  /** /
  //Bezier
   int i;

   glColor3f(1.0, 1.0, 1.0);
   //glLineWidth(5);
   glBegin(GL_LINE_STRIP);
      for (i = 0; i <= 30; i++) 
         glEvalCoord1f((GLfloat) i/30.0);
   glEnd();

  /**/
  char * s = new char[100];
  /** /
  //sprintf(s, "BallX: % .2f\nBallY: % .2f\nBallZ: % .2f", b->getPos().x, b->getPos().y, b->getPos().z);
  if (1.0 / dt > 999.0)
    sprintf(s, "FPS: %08.2f+", 999.0);
  else
    sprintf(s, "FPS: %08.2f", 1.0 / dt);
  
  //std::cout << "Imprimindo FPS na tela: " << s << std::endl;

  /**/
  float vp[4];
  glGetFloatv(GL_VIEWPORT, vp);

  /**/
  sprintf(s, "Casa sendo lida: 2");
  f->startText(); 
    f->print(vp[0] + (10 * vp[2] / Settings::screenWidth), vp[1] + (30 * vp[3] / Settings::screenHeight), s);
  f->endText();
  
  /**/
  sprintf(s, "Valor da variavel temporaria: -");
  f->startText(); 
    f->print(vp[0] + (10 * vp[2] / Settings::screenWidth), vp[1] + (60 * vp[3] / Settings::screenHeight), s);
  f->endText();

  
  /**/
  //std::cout << "Chamando glutSwapBuffers()" << std::endl;
  glutSwapBuffers();
  
  /**/
  delete (s);
  
  /*** limpa vetores ***/
  /**/
  //std::cout << "Chamando cleanup()" << std::endl;
  cleanup();
  
  /**/
}

void MainScreen::processKey(unsigned char key, int x, int y)
{
  switch(key)
  {
    case 27 :
         SimpleEngine::quitApplication();
         break;
    /** /
    case 'p':
    case 'P':
         //if (!b->isTravelling())
         //    b->shoot(CoordF(0,-1,-1), 5.0);
         b[0]->rotate( CoordF(0, -30, 0) );
         break;
    case 'o':
    case 'O':
         b[0]->rotate( CoordF(0, 30, 0) );
         break;
    case '+':
    case '=':
         b[0]->rotate( CoordF(-30, 0, 0) );
         break;
    case '-':
    case '_':
         b[0]->rotate( CoordF(30, 0, 0) );
         break;
    /**/
    case 'w':
    case 'W':
         camera()->dolly(0.1);
         break;
    case 's':
    case 'S':
         camera()->dolly(-0.1);
         break;
    case 'a':
    case 'A':
         camera()->truck(-0.1);
         break;
    case 'd':
    case 'D':
         camera()->truck(0.1);
         break;
    /**/
    case 'q':
    case 'Q':
         camera()->pedestal(0.1);
         break;
    case 'z':
    case 'Z':
         camera()->pedestal(-0.1);
         break;
    /**/
    case '8':
         camera()->tilt(-1);
         break;
    case '2':
         camera()->tilt(1);
         break;
    case '4':
         camera()->pan(1);
         break;
    case '6':
         camera()->pan(-1);
         break;
    case '9':
         camera()->roll(1);
         break;
    case '7':
         camera()->roll(-1);
         break;
    /**/
    case ' ':
         toggleDrawablesLighting();
         break;
    case '0':
         toggleDrawablesWireframe();
         break;
    default:
         break;
  }
  
  glutPostRedisplay();
}

void MainScreen::triggerEvent(int e)
{
  switch(e)
  {
  default:
    break;
  }
}
         
                 
